﻿using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;//排序
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    public static GameManager Instance;
    private GameData data;

    /// <summary>
    /// 是否开始游戏
    /// </summary>
    public bool IsGameStarted { get; set; }
    /// <summary>
    /// 游戏是否结束
    /// </summary>
    public bool IsGameOver { get; set; }
    /// <summary>
    /// 游戏是否暂停
    /// </summary>
    public bool IsPaused { get; set; }
    /// <summary>
    /// 游戏成绩
    /// </summary>
    private int gameScore;
    /// <summary>
    /// 玩家是否移动
    /// </summary>
    public bool PlayerIsMove { get; set; }
    private int gameDiamond;//钻石
    /// <summary>
    /// 是否是重新开始游戏
    /// </summary>
    public static bool isAgainGame = false;

    private bool isFirstGame;//第一次开始游戏
    private bool isMusicOn;//当前音效是否开
    private int[] bestScoreArr;//当前排名  -前三名
    private int selectSkin;//当前选择皮肤
    private bool[] skinUnlocked;//未解锁的皮肤
    private int diamondcount;//钻石数量

    private ManagerVars vars;

    private void Awake()
    {
        Instance = this;
        vars = ManagerVars.GetManagerVars();

        data = new GameData();
        EventCenter.AddListener(EventDefine.AddScore, AddGameScore);
        EventCenter.AddListener(EventDefine.PlayerIsMove, PlayerMove);
        EventCenter.AddListener(EventDefine.AddDiamond, AddGameDiamond);

        //判断当前是否重新开始游戏
        if (GameData.isAgainGame)
        {
            IsGameStarted = true;
        }
        InitGameData();
    }
    /// <summary>
    /// 销毁
    /// </summary>
    private void OnDestroy()
    {
        EventCenter.RemoveListener(EventDefine.AddScore, AddGameScore);
        EventCenter.RemoveListener(EventDefine.PlayerIsMove, PlayerMove);
        EventCenter.RemoveListener(EventDefine.AddDiamond, AddGameDiamond);
    }
    /// <summary>
    /// 获得游戏成绩
    /// </summary>
    public int GetGameScore()
    {
        return gameScore;
    }
    /// <summary>
    /// 添加游戏成绩
    /// </summary>
    private void AddGameScore()
    {
        if (IsGameStarted == false || IsGameOver || IsPaused) return;

        gameScore++;//每次加一
        EventCenter.Broadcast(EventDefine.UpdateScoreText, gameScore);
    }
    /// <summary>
    /// 玩家移动会调用的此方法
    /// </summary>
    private void PlayerMove()
    {
        PlayerIsMove = true;
    }
    /// <summary>
    /// 增加钻石
    /// </summary>
    private void AddGameDiamond()
    {
        gameDiamond++;
        EventCenter.Broadcast(EventDefine.updateDiamondText, gameDiamond);//钻石数量广播出去
    }
    /// <summary>
    /// 获得钻石
    /// </summary>
    /// <returns></returns>
    public int getGameDiamond()
    {
        return gameDiamond;
    }
    /// <summary>
    /// 获得所有钻石
    /// </summary>
    /// <returns></returns>
    public int GetAllDiamond()
    {
        return diamondcount;
    }
    /// <summary>
    /// 更新钻石数量
    /// </summary>
    /// <returns></returns>
    public void UpdateDiamond(int diamond)
    {
        diamondcount += diamond;
        Save();
    }
    /// <summary>
    /// 保存成绩
    /// </summary>
    /// <param name="score"></param>
    public void SaveScore(int score)
    {
        //将数组转换成List
        List<int> list = bestScoreArr.ToList();

        /**
         * 从小到大排序 
         * 提示需要传入的comparison就是(x, y) => (x.CompareTo(y))
         * x,y做比较
         * 
         * 需要从大到小所以加一个-号
         */
        list.Sort((x, y) => (-x.CompareTo(y)));
        bestScoreArr = list.ToArray();//50 20 10

        int index = -1;
        for (int i = 0; i < bestScoreArr.Length; i++)
        {
            if (score>bestScoreArr[i])
            {
                index = i;
            }
        }
        //没有符合的条件
        if (index == -1) return;
        //从重新-冒泡排序  
        for (int i = bestScoreArr.Length-1; i>index ; i++)
        {
            //前一位给后一位赋值
            bestScoreArr[i] = bestScoreArr[i] - 1;
        }
        bestScoreArr[index] = score;

        Save();
    }
    /// <summary>
    /// 获得最高分
    /// </summary>
    /// <param name="score"></param>
    public int GetBestScore()
    {
        //Linq提供的方法
        return bestScoreArr.Max();
    }
    /// <summary>
    /// 获得最高分成绩数组
    /// </summary>
    /// <param name="score"></param>
    public int[] GetBestArr()
    {
        //将数组转换成List
        List<int> list = bestScoreArr.ToList();

        /**
         * 从小到大排序 
         * 提示需要传入的comparison就是(x, y) => (x.CompareTo(y))
         * x,y做比较
         * 
         * 需要从大到小所以加一个-号
         */
        list.Sort((x, y) => (-x.CompareTo(y)));
        bestScoreArr = list.ToArray();//50 20 10
        return bestScoreArr;
    }

    /// <summary>
    /// 获取当前皮肤是否解锁
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    public bool GetSkinUnlocked(int index)
    {
        return skinUnlocked[index];
    }
    /// <summary>
    /// 设置当前皮肤解锁
    /// </summary>
    /// <param name="index"></param>
    public void SetSkinUnlocked(int index)
    {
        skinUnlocked[index] = true;
        Save();
    }
    /// <summary>
    /// 设置当前选中皮肤
    /// </summary>
    /// <param name="index"></param>
    public void SetSelectSkin(int index)
    {
        selectSkin = index;
        Save();
    } 
    /// <summary>
      /// 获得当前选中皮肤
      /// </summary>
      /// <param name="index"></param>
    public int GetSelectedSkin()
    {
        return selectSkin;
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space)) {
            isFirstGame = true;
            InitGameData();
        }
    }
    /// <summary>
    /// 设置游戏音效是否开启
    /// </summary>
    public void SetIsMusicOn(bool value) 
    {
        isMusicOn = value;
        Save();
    }
    /// <summary>
    /// 获取是否开启
    /// </summary>
    public bool GetIsMusicOn()
    {
        return isMusicOn;
    }
    /// <summary>
    /// 初始化游戏数据
    /// </summary>
    private void InitGameData() 
    {
        //Debug.Log("111");
        //读取数据
        Read();
        //如果数据不为空
        if (data!=null)
        {
            //本地是否第一次读取
            isFirstGame = data.GetIsFitstGame();
        }
        else
        {
            isFirstGame = true;
        }
        //如果第一次开始游戏
        if (isFirstGame)
        {
            isFirstGame = false;//不是第一次了，避免死循环
            isMusicOn = true;
            bestScoreArr = new int[3];
            selectSkin = 0;//第一个皮肤
            skinUnlocked = new bool[vars.skinSpriteList.Count];//数组长度
            skinUnlocked[0] = true;//未解锁的第一个
            diamondcount = 10;//钻石

            //TOTO 解决data为空现象
          // data = new GameData();
            Save();
        }
        else
        {
            isMusicOn = data.GetIsMusicOn();
            bestScoreArr = data.GetBestScoreArr();
            selectSkin = data.GetSelectSkin();
            skinUnlocked = data.GetSkinUnlocked();
            diamondcount = data.GetDiamondcount();
        }
    }
    /// <summary>
    /// 重置数据
    /// </summary>
    public void ResetData() 
    {
        isFirstGame = false;//不是第一次了，避免死循环
        isMusicOn = true;
        bestScoreArr = new int[3];
        selectSkin = 0;//第一个皮肤
        skinUnlocked = new bool[vars.skinSpriteList.Count];//数组长度
        skinUnlocked[0] = true;//未解锁的第一个
        diamondcount = 10;//钻石

        Save();
    }
    /// <summary>
    /// 数据存储
    /// 
    /// 文件流 引入system.IO
    /// 
    /// </summary>
    private void Save() 
    {
        try
        {
            BinaryFormatter bf = new BinaryFormatter();
            //创建文件的写入流  自动释放fs.close
            using (FileStream fs=File.Create(Application.persistentDataPath+ "/GameData.data"))
            {
                //拿到数据集中的字段，放到data中
                data.SetBestScoreArr(bestScoreArr);
                data.SetDiamondcount(diamondcount);
                data.SetIsFitstGame(isFirstGame);
                data.SetIsMusicOn(isMusicOn);
                data.SetSelectSkin(selectSkin);
                data.SetSkinUnlocked(skinUnlocked);

                //写入本地
                bf.Serialize(fs,data);//序列化
            }
        }
        catch (System.Exception e)
        {
            Debug.Log(e.Message);
        }
    }
    /// <summary>
    /// 读取
    /// </summary>
    private void Read()
    {
        try
        {
            BinaryFormatter bf = new BinaryFormatter();
            using (FileStream fs=File.Open(Application.persistentDataPath + "/GameData.data", FileMode.Open))
            {
                data=(GameData)bf.Deserialize(fs);//反序列化  返回值object
            }
        }
        catch (System.Exception e)
        {
            Debug.Log(e.Message);
        }
    }
}
